home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac Power 1996 October
/
MACPOWER-1996-10.ISO.7z
/
MACPOWER-1996-10.ISO
/
AMUG
/
Internet_31
/
NetCacheResolver 0.9d6
/
NetCacheResolver 0.9d6 ト
/
library
/
NCR_Message.c
< prev
next >
Wrap
Text File
|
1996-05-12
|
12KB
|
582 lines
// #define DEBUG_ANSI 1
// Basic Toolkit, 1994 (C) Mizutori Tetsuya
// - MessageUtils.c, 1994/10/6, 1995/8/6
#include <stdio.h>
#include <stdarg.h>
#include "NCR_Message.h"
#ifdef COMMENT
[Flag character]
- Left-justify
+ print with a plus sign '+'
' ' Prefix a number with a space
# %#s for Pascal-style string
0 pad the field with leading zeros
[Field size]
* Use the next argument (integer) as the field size
[Argument size]
h for short
l,L for long
[Conversion characters]
c a single character
s a string, with # for Str255
e,E,f a signed decimal floating/fixed - point number
g,G
d,i,u a signed/unsigned decimal integer
o an unsigned octal integer
x,X an unsigned hexadecimal integer
n,p an eight-digit hexadecimal value
% a percent sign
S,P Macintosh Pascal-style string for Str255
t,T Macintosh Toolbox types, eg. OSType, four-byte constant
#endif /*COMMENT */
// define constants
#define EOS '¥0'
enum {
kflag_none = 0, /* no */
kflag_short = 1, /* h */
kflag_long = 2, /* l */
kflag_ldouble = 3, /* L */
kflag_pound = 4, /* # */
kflag_aster = 5, /* * */
kflag_left = 6, /* - */
kflag_plus = 7, /* + */
kflag_space = 8, /* ' ' */
kflag_zeros = 9, /* %0 */
kflag_dot = 10 /* . */
};
#define kHexShortFS 4
#define kHexLongFS 8
#define kOctShortFS 6
#define kOctLongFS 11
// prptotype
/***** static functions *****/
static void vsMessage ( char *text, const char *format, va_list ap );
static Boolean TestType ( short c );
static char * GetDirective ( char *p, long *flag, long *fieldSize );
static void WriteChars ( char *cstr );
static void WriteChar( short c );
static StringPtr NumToHex ( unsigned long n, StringPtr format, short digits );
static StringPtr NumToOct ( unsigned long n, StringPtr format, short digits );
/***** message test *****/
#ifdef TEST
void MessageTest ( void )
{
short i;
char c = 'm';
short n = 33;
long x = 3333333;
double f = 333.333;
OSType t = 'odoc';
char s[8] = "yes!";
char s2[16] = "01234567890123";
Str31 p = "¥ppascal!";
// for (i=1;i<=100;++i) {
// Message( "This is %3d lines. Mizutori Tetsuya + Mizutori Misuzu¥n", i );
// }
Message("¥n");
Message("test '%010d'='%-10d' +'%010s'='%-010s'¥n",n,n,s,s);
Message("test '%010s'='%s' +'%010s'='%s'¥n",s,s,s2,s2);
Message("OSType('%4s') = ('%-10t')¥n",&t, t);
Message("string('%10s'), ('%-10S')¥n",s,p);
Message("short=%d, hex=0x%*lx¥ndouble=%lf, pointer=%p¥n" ¥
"cstr=%s, char='%c'¥n" ¥
"pstr=%#s¥n",
n,7,x,f,&s,s,c,p);
}
#endif /* TEST */
/***** set up *****/
#define MAXLENGTH 2048
void Message ( const char *format, ... )
{
va_list ap;
char text[MAXLENGTH];
va_start( ap, format );
vsMessage( text, format, ap );
va_end( ap );
WriteChars( text );
}
void sMessage ( char *text, const char *format, ... )
{
va_list ap;
va_start( ap, format );
vsMessage( text, format, ap );
va_end( ap );
}
/***** Message Window *****/
#define kBaseResID 128
#define kMoveToFront (WindowPtr) -1L
/***** Constants & Globals *****/
short kLeftMargin = 4;
short kRowStart = 285;
short kFontSize = 9;
short kRowHeight = 11; /* kFontSize+2 */
short kHorizontalOffset = 0;
WindowPtr gMsgWindow = nil;
/***** create MessageBoard window *****/
void NewMessage ( void )
{
WindowPtr window;
Rect windRect;
GrafPtr oldPort;
window = GetNewWindow( kBaseResID, nil, kMoveToFront );
if ( window == nil ) {
SysBeep(10);
ExitToShell(); }
GetPort( &oldPort );
SetPort( window );
TextSize( kFontSize );
ShowWindow( window );
gMsgWindow = window;
SetPort( oldPort );
}
/***** WriteTextln *****/
static void WriteChars ( char *text )
{
long i = 0, k = 0;
char c;
Str255 str = "¥p";
// while ( (c=text[i++]) != EOS ) WriteChar( (unsigned char) c );
while ( (c=text[i++]) != EOS ) {
if (c == '¥n' || c == '¥r' ) {
str[0] = k;
WriteTextln(str);
k = 0;
} else if ( k > 250 ) {
str[0] = k;
WriteText(str);
k = 0;
} else {
str[++k] = c;
}
}
if ( k > 0 ) {
str[0] = k;
WriteText( str );
}
}
static void WriteChar( short c )
{
GrafPtr oldPort;
if ( gMsgWindow == nil ) return;
GetPort( &oldPort );
SetPort( gMsgWindow );
if ( c == '¥n' || c == '¥r' ) WriteTextln("¥p");
else DrawChar( c );
SetPort( oldPort );
}
void WriteTextln ( StringPtr text )
{
RgnHandle tempRgn;
WindowPtr window;
GrafPtr oldPort;
if ( gMsgWindow == nil ) return;
GetPort( &oldPort );
SetPort( gMsgWindow );
DrawString( text );
window = FrontWindow();
tempRgn = NewRgn();
ScrollRect( &window->portRect, kHorizontalOffset, -kRowHeight, tempRgn );
DisposeRgn( tempRgn );
MoveTo( kLeftMargin, (window->portRect).bottom - 2 );
SetPort( oldPort );
}
void WriteText ( StringPtr text )
{
GrafPtr oldPort;
if ( gMsgWindow == nil ) return;
GetPort( &oldPort );
SetPort( gMsgWindow );
DrawString( text );
SetPort( oldPort );
}
void WriteTextNumb ( long value )
{
Str31 text;
GrafPtr oldPort;
if ( gMsgWindow == nil ) return;
GetPort( &oldPort );
SetPort( gMsgWindow );
NumToString( value, text );
DrawString( text );
SetPort( oldPort );
}
void WriteTextType ( OSType type )
{
Str32 text = "¥p****";
GrafPtr oldPort;
if ( gMsgWindow == nil ) return;
GetPort( &oldPort );
SetPort( gMsgWindow );
BlockMove( &type, &text[1], 4);
DrawString( text );
SetPort( oldPort );
}
void WriteTextPeek ( Ptr dataPtr, Size length )
{
long i;
// Size hSize;
unsigned char *p, c;
Str31 text = "¥p*";
Str31 text2 = "¥p¥¥**";
unsigned char hex[17] = "0123456789abcdef";
GrafPtr oldPort;
if ( gMsgWindow == nil ) return;
GetPort( &oldPort );
SetPort( gMsgWindow );
p = (unsigned char *) dataPtr;
// hSize = GetPtrSize( dataPtr );
if ( length > 8 ) WriteTextln("¥p");
for ( i=0; i<length; ++i ) {
if ( (i > 0) && ( (i % 16) == 0 ) ) WriteTextln("¥p");
c = p[i];
//if ( c < ' ' || c > 0x7E ) c = '.';
if ( c < ' ' || c > 0x7E ) {
text2[2] = hex[(c>>4) & 0x0f]; text2[3]=hex[c & 0x0f];
DrawString( text2 );
} else {
text[1] = c;
DrawString( text );
}
}
SetPort( oldPort );
}
/***** static functions *****/
#define bitTst(flag,bit) ( (Boolean) ( ((flag) & (1 << (bit))) != 0 ) )
#define bitSet(flag,bit) ( flag |= (1 << (bit)) )
#define va_arg_int( ap, flag ) ¥
( bitTst(flag,kflag_long) ? va_arg(ap,long) : va_arg(ap,short) )
#define va_arg_uint( ap, flag ) ¥
( bitTst(flag,kflag_long) ? va_arg(ap,unsigned long) : va_arg(ap,unsigned short) )
#define va_arg_float( ap, flag ) ¥
( bitTst(flag,kflag_long) ? va_arg(ap,long double) : va_arg(ap,short double) )
#define FieldSize(fs,shortfs,longfs) ¥
( (fs) > 0 ? (fs) : ( bitTst(flag,kflag_long) ? (longfs) : (shortfs) ) )
static void vsMessage ( char *text, const char *format, va_list ap )
{
// va_list ap;
long n;
short i, j, k, h;
char c, d, zeroChar;
char *p, *q, *s;
long value;
unsigned long uvalue;
long double fvalue;
long flag;
long digits;
Boolean shiftLeft;
Str63 str;
// va_start( ap, format );
n = 0; p = (char *) format;
while ( (c=*(p++)) != EOS /* && n<MAXLENGTH-20 */ ) {
if ( c != '%' ) { text[n++] = c; continue; }
digits = 0;
q = p;
p = GetDirective ( p, &flag, &digits );
if ( (c=*(p++)) == EOS ) { --p; break; }
zeroChar = ( bitTst(flag,kflag_zeros) ? '0' : ' ' );
shiftLeft = bitTst( flag, kflag_left );
if ( bitTst( flag, kflag_aster ) && TestType( (unsigned char) c ) ) {
digits = va_arg( ap, short ); }
switch ( c ) {
case_int:
case 'i':
case 'd':
value = va_arg_int( ap, flag );
NumToString( value, str );
goto case_printdigit;
break;
case 'u':
value = va_arg_uint( ap, flag );
NumToString( value, str );
goto case_printdigit;
break;
case_hex:
case 'x':
case 'X':
value = va_arg_uint( ap, flag );
NumToHex( value, str, FieldSize(digits,kHexShortFS,kHexLongFS) );
goto case_printdigit;
break;
case_oct:
case 'o':
value = va_arg_uint( ap, flag );
NumToOct( value, str, FieldSize(digits,kOctShortFS,kOctLongFS) );
goto case_printdigit;
break;
case_float:
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
fvalue = va_arg_float( ap, flag );
value = fvalue;
NumToString( value, str );
goto case_printdigit;
break;
case_pointer:
case 'p':
case 'n':
value = (unsigned long) va_arg( ap, void * );
NumToHex( value, str, kHexLongFS );
goto case_printdigit;
break;
case 't':
case 'T':
value = (unsigned long) va_arg( ap, void * );
str[0] = sizeof(OSType);
BlockMove( &value, &str[1], str[0] );
goto case_printdigit;
break;
case_printdigit:
k = str[0];
s = (char *) &str[1];
goto case_printstr;
break;
case 's':
s = va_arg( ap, char * );
if ( bitTst( flag, kflag_pound ) ) {
if ( digits == 0 )
goto case_pstr0;
else
goto case_pstr1;
} else {
if ( digits == 0 )
goto case_cstr0;
else
goto case_cstr1;
}
break;
case 'S':
case 'P':
s = va_arg( ap, char * );
goto case_pstr0;
break;
case_cstr0:
k = 0; while ( s[k] != EOS ) ++k;
goto case_printstr;
break;
case_cstr1:
k = 0; while ( s[k] != EOS && k<digits ) ++k;
goto case_printstr;
break;
case_pstr0:
case_pstr1:
k = * (unsigned char *) s;
++s;
goto case_printstr;
break;
case_printstr:
// digits = field width
// k = string length
// *s = start of string
h = digits - k; if ( h < 0 ) h = 0;
if ( ! shiftLeft )
while ( --h >= 0 ) text[n++] = zeroChar;
while ( --k >= 0 ) text[n++] = *(s++);
if ( shiftLeft )
while ( --h >= 0 ) text[n++] = zeroChar;
break;
case_char:
case 'c':
value = va_arg( ap, unsigned short ); /* not 'char' */
text[n++] = value;
break;
case '%':
text[n++] = c;
break;
case_none:
default:
p = q;
text[n++] = '%';
break;
}
}
text[n++] = EOS;
// va_end( ap );
for (i=1;i<=n;++i) if ( text[i] == '¥n' ) text[i] = '¥r';
}
static Boolean TestType ( short c )
{
register short n = 0;
register short d;
char types[] = "dioxXucsfeEgGpntTSP";
while ( (d=types[n++]) != EOS )
if ( c == d ) return true;
return false;
}
static char * GetDirective ( char *p, long *flag, long *fieldSize )
{
char c;
long fflag = 0;
long n = 0;
Boolean done = false;
char text[32] = "";
while ( (c=*p) != EOS && ! done ) { ++p;
if ( '0' <= c && c <= '9' ) {
if ( n < 31 && ! bitTst(fflag,kflag_dot) ) {
text[n++] = c; text[n] = EOS; }
continue; }
switch ( c ) {
case '+': bitSet( fflag, kflag_plus ); break;
case '-': bitSet( fflag, kflag_left ); break;
case ' ': bitSet( fflag, kflag_space ); break;
case '.': bitSet( fflag, kflag_dot ); break;
case 'h': bitSet( fflag, kflag_short ); break;
case 'l': bitSet( fflag, kflag_long ); break;
case 'L': bitSet( fflag, kflag_long ); break;
case '*': bitSet( fflag, kflag_aster ); break;
case '#': bitSet( fflag, kflag_pound ); break;
default: --p; done = true; break;
}
}
if ( n > 0 && text[0] == '0' ) bitSet( fflag, kflag_zeros );
c2pstr( text );
StringToNum( (StringPtr) text, fieldSize );
*flag = fflag;
return p;
}
/***** hex & oct number conversion *****/
static char *conv = "0123456789abcdef";
static StringPtr NumToHex ( unsigned long n, StringPtr format, short digits )
{
// static StringPtr format = "¥p00000000";
unsigned long i;
if ( digits > 8 || digits < 0 ) digits = 8;
format[0] = digits; /* adjust length byte of output string */
for ( i=0; i<digits; ( n>>=4, ++i) )
format[ digits-i ] = conv[ n & 0x0f ];
return format;
}
static StringPtr NumToOct ( unsigned long n, StringPtr format, short digits )
{
// static StringPtr format = "¥p000000000000";
unsigned long i;
if ( digits > 12 || digits < 0 ) digits = 12;
format[0] = digits; /* adjust length byte of output string */
for ( i=0; i<digits; ( n>>=3, ++i) )
format[ digits-i ] = conv[ n & 0x07 ];
return format;
}
// end of program